package com.han.demo.springbootmodulelistener;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;

/**
 * @author hanjl
 * @Description 事件管理器:
 *                       1.扫描所有的监听器并添加
 *                       2.发布事件
 *                       3.判断哪些监听器对发布的事件感兴趣并调用监听器的监听方法
 * @ClassName MyApplicationListenerManager
 * @createTime 2021/11/17 18:09
 */
@Component
@Slf4j
public class MyApplicationListenerManager {

    static List<IMyApplicationListener<?>> listenerList = new ArrayList<IMyApplicationListener<?>>();

    /**
     * 事件管理器手动添加所有监听器
     * @param listener
     */
    public static void addListener(IMyApplicationListener<?> listener){
        listenerList.add(listener);
    }

    /**
     * 遍历所有监听器判断有哪些监听器对这个事件感兴趣
     * @param event
     */
    public static void pushEvent(MyFileEvent event){
        for (IMyApplicationListener listener : listenerList) {
            //获取当前监听器所关联的泛型事件
            Class clazz = (Class)((ParameterizedType)listener.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0];
            //判断监听器的参数泛型是不是当前事件的泛型，如果匹配则说明当前监听器对该发布的事件感兴趣并会触发监听器的监听方法
            if(clazz.equals(event.getClass())){
                log.info("有监听器对该事件: "+event.getClass().getName()+"感兴趣...");
                listener.onMessage(event);
            }
        }
    }


}
